home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld files / Sources / Sprite.c < prev    next >
Encoding:
Text File  |  1999-01-12  |  49.2 KB  |  1,875 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    Sprite.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    implementation of the sprites
  7. ///--------------------------------------------------------------------------------------
  8.  
  9.  
  10. #ifndef __SWCOMMON__
  11. #include "SWCommonHeaders.h"
  12. #endif
  13.  
  14. #ifndef __MEMORY__
  15. #include <Memory.h>
  16. #endif
  17.  
  18. #ifndef __SPRITEWORLDUTILS__
  19. #include "SpriteWorldUtils.h"
  20. #endif
  21.  
  22. #ifndef __SPRITEWORLD__
  23. #include "SpriteWorld.h"
  24. #endif
  25.  
  26. #ifndef __SPRITE__
  27. #include "Sprite.h"
  28. #endif
  29.  
  30. #ifndef __SPRITEFRAME__
  31. #include "SpriteFrame.h"
  32. #endif
  33.  
  34. #ifndef __BLITPIXIE__
  35. #include "BlitPixie.h"
  36. #endif
  37.  
  38. extern RgnHandle         gCollisionSectRgn;
  39. extern RgnHandle        gCollisionSpareRgn;
  40. extern SInt8             gSWmmuMode;
  41.  
  42.  
  43. ///--------------------------------------------------------------------------------------
  44. //    SWCreateSprite
  45. ///--------------------------------------------------------------------------------------
  46.  
  47. SW_FUNC OSErr SWCreateSprite(
  48.     SpritePtr* newSpriteP,
  49.     void* spriteStorageP,
  50.     short maxFrames)
  51. {
  52.     OSErr err = noErr;
  53.     SpritePtr tempSpriteP;
  54.     Size frameArraySize;
  55.  
  56.     *newSpriteP = NULL;
  57.  
  58.     tempSpriteP =  (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
  59.  
  60.     if (tempSpriteP != NULL)
  61.     {
  62.         frameArraySize = (Size)maxFrames * sizeof(FramePtr);
  63.  
  64.         tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
  65.  
  66.         if (tempSpriteP->frameArray != NULL)
  67.         {
  68.             tempSpriteP->parentSpriteLayerP = NULL;
  69.             tempSpriteP->nextSpriteP = NULL;
  70.             tempSpriteP->prevSpriteP = NULL;
  71.  
  72.                 // initialize drawing fields
  73.             tempSpriteP->isVisible = true;
  74.             tempSpriteP->needsToBeDrawn = true;
  75.             tempSpriteP->needsToBeErased = false;
  76.             tempSpriteP->destFrameRect.left = 0;
  77.             tempSpriteP->destFrameRect.top = 0;
  78.             tempSpriteP->destFrameRect.right = 0;
  79.             tempSpriteP->destFrameRect.bottom = 0;
  80.             tempSpriteP->oldFrameRect.left = 0;
  81.             tempSpriteP->oldFrameRect.top = 0;
  82.             tempSpriteP->oldFrameRect.right = 0;
  83.             tempSpriteP->oldFrameRect.bottom = 0;
  84.             tempSpriteP->deltaFrameRect.left = 0;
  85.             tempSpriteP->deltaFrameRect.top = 0;
  86.             tempSpriteP->deltaFrameRect.right = 0;
  87.             tempSpriteP->deltaFrameRect.bottom = 0;
  88.             tempSpriteP->frameDrawProc = SWStdSpriteDrawProc;
  89.             tempSpriteP->tileDepth = 1;
  90.                 
  91.                 // initialize drawing fields for scrolling routines
  92.             tempSpriteP->destOffscreenRect.left = 0;
  93.             tempSpriteP->destOffscreenRect.top = 0;
  94.             tempSpriteP->destOffscreenRect.right = 0;
  95.             tempSpriteP->destOffscreenRect.bottom = 0;
  96.             tempSpriteP->oldOffscreenRect.left = 0;
  97.             tempSpriteP->oldOffscreenRect.top = 0;
  98.             tempSpriteP->oldOffscreenRect.right = 0;
  99.             tempSpriteP->oldOffscreenRect.bottom = 0;
  100.             tempSpriteP->oldRectIsVisible = false;
  101.  
  102.                 // initialize frame fields
  103.             tempSpriteP->frameArrayIsShared = false;
  104.             tempSpriteP->curFrameP = NULL;
  105.             tempSpriteP->numFrames = 0;
  106.             tempSpriteP->maxFrames = maxFrames;
  107.             tempSpriteP->frameTimeInterval = -1;
  108.             tempSpriteP->timeOfLastFrameChange = 0;
  109.             tempSpriteP->frameAdvance = 1;
  110.             tempSpriteP->curFrameIndex = 0;
  111.             tempSpriteP->firstFrameIndex = 0;
  112.             tempSpriteP->lastFrameIndex = 0;
  113.             tempSpriteP->frameChangeProc = NULL;
  114.  
  115.                 // initialize movement fields
  116.             tempSpriteP->moveTimeInterval = 0;
  117.             tempSpriteP->timeOfLastMove = 0;
  118.             tempSpriteP->horizMoveDelta = 0;
  119.             tempSpriteP->vertMoveDelta = 0;
  120.             tempSpriteP->moveBoundsRect.left = 0;
  121.             tempSpriteP->moveBoundsRect.top = 0;
  122.             tempSpriteP->moveBoundsRect.right = 0;
  123.             tempSpriteP->moveBoundsRect.bottom = 0;
  124.             tempSpriteP->spriteMoveProc = NULL;
  125.  
  126.             tempSpriteP->spriteCollideProc = NULL;
  127.             
  128.             tempSpriteP->sharedPictGWorld = NULL;
  129.             tempSpriteP->sharedMaskGWorld = NULL;
  130.             tempSpriteP->spriteRemoval = kSWDontRemoveSprite;
  131.             tempSpriteP->frameAdvanceMode = kSWWrapAroundMode;
  132.             
  133.             tempSpriteP->scaledWidth = -1;
  134.             tempSpriteP->scaledHeight = -1;
  135.             
  136.             tempSpriteP->userData = 0;
  137.  
  138.                 // the sprite has been successfully created
  139.             *newSpriteP = tempSpriteP;
  140.         }
  141.         else
  142.         {
  143.             err = MemError();
  144.  
  145.             DisposePtr((Ptr)tempSpriteP);
  146.         }
  147.     }
  148.     else
  149.     {
  150.         err = MemError();
  151.     }
  152.  
  153.     SWSetStickyIfError( err );
  154.     return err;
  155. }
  156.  
  157.  
  158. ///--------------------------------------------------------------------------------------
  159. //    SWCreateSpriteFromCicnResource
  160. ///--------------------------------------------------------------------------------------
  161.  
  162. SW_FUNC OSErr SWCreateSpriteFromCicnResource(
  163.     SpriteWorldPtr destSpriteWorldP,
  164.     SpritePtr* newSpriteP,
  165.     void* spriteStorageP,
  166.     short cIconID,
  167.     short maxFrames,
  168.     MaskType maskType)
  169. {
  170.     OSErr             err;
  171.     SpritePtr         tempSpriteP;
  172.     FramePtr         newFrameP;
  173.     short             frame;
  174.     
  175.     SW_ASSERT(destSpriteWorldP != NULL);
  176.  
  177.     *newSpriteP = NULL;
  178.  
  179.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  180.     
  181.     if (err == noErr)
  182.     {
  183.         for (frame = 0; frame < maxFrames; frame++)
  184.         {
  185.             err = SWCreateFrameFromCicnResource(destSpriteWorldP, &newFrameP, 
  186.                     cIconID + frame, maskType);
  187.  
  188.             if (err == noErr)
  189.             {
  190.                 err = SWAddFrame(tempSpriteP, newFrameP);
  191.             }
  192.  
  193.             if (err != noErr)
  194.             {
  195.                 SWDisposeFrame(&newFrameP);
  196.                 SWDisposeSprite(&tempSpriteP);
  197.                 break;
  198.             }
  199.         }
  200.  
  201.         if (err == noErr)
  202.         {
  203.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  204.             SWSetCurrentFrameIndex(tempSpriteP, 0);
  205.             *newSpriteP = tempSpriteP;
  206.         }
  207.     }
  208.  
  209.     SWSetStickyIfError( err );
  210.     return err;
  211. }
  212.  
  213.  
  214. ///--------------------------------------------------------------------------------------
  215. //    SWCreateSpriteFromPictResource
  216. ///--------------------------------------------------------------------------------------
  217.  
  218. SW_FUNC OSErr SWCreateSpriteFromPictResource(
  219.     SpriteWorldPtr destSpriteWorldP,
  220.     SpritePtr* newSpriteP,
  221.     void* spriteStorageP,
  222.     short pictResID,
  223.     short maskResID,
  224.     short maxFrames,
  225.     MaskType maskType)
  226. {
  227.     OSErr             err;
  228.     SpritePtr         tempSpriteP;
  229.     FramePtr         newFrameP;
  230.     short             frame;
  231.     
  232.     SW_ASSERT(destSpriteWorldP != NULL);
  233.     
  234.     *newSpriteP = NULL;
  235.  
  236.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  237.  
  238.     if (err == noErr)
  239.     {
  240.         for (frame = 0; frame < maxFrames; frame++)
  241.         {
  242.             err = SWCreateFrameFromPictResource(destSpriteWorldP, &newFrameP, 
  243.                     pictResID + frame, maskResID + frame, maskType);
  244.  
  245.             if (err == noErr)
  246.             {
  247.                 err = SWAddFrame(tempSpriteP, newFrameP);
  248.             }
  249.  
  250.             if (err != noErr)
  251.             {
  252.                 SWDisposeFrame(&newFrameP);
  253.                 SWDisposeSprite(&tempSpriteP);
  254.                 break;
  255.             }
  256.         }
  257.  
  258.         if (err == noErr)
  259.         {
  260.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  261.             SWSetCurrentFrameIndex(tempSpriteP, 0);
  262.             *newSpriteP = tempSpriteP;
  263.         }
  264.     }
  265.     
  266.     SWSetStickyIfError( err );
  267.     return err;
  268. }
  269.  
  270.  
  271. ///--------------------------------------------------------------------------------------
  272. //    CalcMaxWidthHeight
  273. ///--------------------------------------------------------------------------------------
  274. static void CalcMaxWidthHeight( 
  275.     RectArrayPtr newRectArrayP, 
  276.     short *maxWidthP, 
  277.     short *maxHeightP )
  278. {
  279.     short         frame;
  280.     Rect         *rectP;
  281.     short         maxWidth, maxHeight;
  282.     
  283.     
  284.     maxWidth = 0;
  285.     maxHeight = 0;
  286.     
  287.     rectP = &newRectArrayP->frameRects[0];
  288.     for( frame = 0; frame < newRectArrayP->numFrames; frame++ ) 
  289.     {
  290.         if ( rectP->right - rectP->left > maxWidth ) 
  291.         {
  292.             maxWidth = rectP->right - rectP->left;
  293.         }
  294.         if ( rectP->bottom - rectP->top > maxHeight ) 
  295.         {
  296.             maxHeight = rectP->bottom - rectP->top;
  297.         }
  298.         rectP++;
  299.     }
  300.     *maxWidthP = maxWidth;
  301.     *maxHeightP =maxHeight;
  302. }
  303.  
  304.  
  305. ///--------------------------------------------------------------------------------------
  306. //    SWCreateSpriteFromSinglePict
  307. ///--------------------------------------------------------------------------------------
  308.  
  309. SW_FUNC OSErr SWCreateSpriteFromSinglePict(
  310.     SpriteWorldPtr destSpriteWorldP,
  311.     SpritePtr* newSpriteP,
  312.     void* spriteStorageP,
  313.     short pictResID,
  314.     short maskResID,
  315.     short frameDimension,
  316.     short borderWidth,
  317.     MaskType maskType)
  318. {
  319.     OSErr             err = noErr;
  320.     Handle            rectArrayHndl;
  321.     RectArrayPtr    newRectArrayP;
  322.     PicHandle        tempPic;
  323.     GWorldPtr        tempPictGWorldP;
  324.     GWorldPtr        tempMaskGWorldP;
  325.     GWorldPtr        tempTempMaskGWorldP;
  326.     Rect            frameRect;
  327.     Boolean            verticalStrip;
  328.     SpritePtr         tempSpriteP;
  329.     FramePtr         newFrameP;
  330.     short             maxFrames;
  331.     short             frame;
  332.     short            maxWidth, maxHeight;
  333.     
  334.     SW_ASSERT(destSpriteWorldP != NULL);
  335.  
  336.     tempPictGWorldP = NULL;
  337.     tempMaskGWorldP = NULL;
  338.     *newSpriteP = NULL;
  339.     rectArrayHndl = NULL;
  340.     
  341.     if ( frameDimension == 0 )
  342.     {
  343.         rectArrayHndl = Get1Resource( 'nrct', pictResID );
  344.     
  345.         if ( rectArrayHndl == NULL )
  346.         {
  347.             err = MemError();
  348.             if ( err == noErr )
  349.                 err = resNotFound;
  350.         }
  351.         else
  352.         {
  353.             HLock( rectArrayHndl );
  354.             newRectArrayP = (RectArrayPtr)*rectArrayHndl;
  355.             maxFrames = newRectArrayP->numFrames;
  356.             CalcMaxWidthHeight( newRectArrayP, &maxWidth, &maxHeight );
  357.         }
  358.     }
  359.     else
  360.     {
  361.         tempPic = GetPicture( pictResID );
  362.         if ( tempPic == nil )
  363.         {
  364.             err = MemError();
  365.             if ( err == noErr )
  366.                 err = resNotFound;
  367.         }
  368.         else
  369.         {
  370.             frameRect = (**(tempPic)).picFrame;
  371.             OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
  372.             ReleaseResource( (Handle)tempPic );
  373.             if ( frameRect.right-frameRect.left < frameRect.bottom-frameRect.top )
  374.             {
  375.                 verticalStrip = true;
  376.                 maxFrames = frameRect.bottom/frameDimension;
  377.                 frameRect.bottom = -borderWidth;
  378.                 maxWidth = frameRect.right-frameRect.left;
  379.                 maxHeight = frameDimension;
  380.             }
  381.             else
  382.             {
  383.                 verticalStrip = false;
  384.                 maxFrames = frameRect.right/frameDimension;
  385.                 frameRect.right = -borderWidth;
  386.                 maxWidth = frameDimension;
  387.                 maxHeight = frameRect.bottom-frameRect.top;
  388.             }
  389.         }
  390.     }
  391.     
  392.     if ( err == noErr )
  393.     {    
  394.         err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  395.     
  396.         if (err == noErr)
  397.         {
  398.             err = SWCreateGWorldFromPictResource( destSpriteWorldP, &tempPictGWorldP, pictResID );
  399.             if ( err == noErr && maskType != kNoMask )
  400.                 err = SWCreateGWorldFromPictResource( 
  401.                     destSpriteWorldP, &tempMaskGWorldP, maskResID );
  402.             if (err == noErr)
  403.             {    
  404.                 if ( pictResID == maskResID && tempMaskGWorldP != NULL )
  405.                 {
  406.                     err = SWBlackenGWorld( tempMaskGWorldP );
  407.                 }
  408.             }
  409.             
  410.             if (err == noErr)
  411.             {
  412.                 err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, maxWidth, 
  413.                     maxHeight, maskType );
  414.             }
  415.             
  416.             if (err == noErr)
  417.             {
  418.                 for (frame = 0; frame < maxFrames; frame++)
  419.                 {
  420.                     if ( frameDimension == 0 )
  421.                     {
  422.                         frameRect = newRectArrayP->frameRects[frame];
  423.                     }
  424.                     else
  425.                     {
  426.                         if ( verticalStrip )
  427.                         {
  428.                             frameRect.top = frameRect.bottom + borderWidth;
  429.                             frameRect.bottom = frameRect.top + frameDimension;
  430.                         }
  431.                         else
  432.                         {
  433.                             frameRect.left = frameRect.right + borderWidth;
  434.                             frameRect.right = frameRect.left + frameDimension;
  435.                         }
  436.                     }
  437.                     
  438.                     err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
  439.                             tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
  440.         
  441.                     if (err == noErr)
  442.                     {
  443.                         err = SWAddFrame(tempSpriteP, newFrameP);
  444.                     }
  445.         
  446.                     if (err != noErr)
  447.                     {
  448.                         SWDisposeFrame(&newFrameP);
  449.                         SWDisposeSprite(&tempSpriteP);
  450.                         break;
  451.                     }
  452.                 }
  453.                 SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
  454.             }
  455.                 
  456.             if (err == noErr)
  457.             {
  458.                     // make a pixel mask
  459.                 if ((maskType & kPixelMask) != 0)
  460.                 {
  461.                     if (destSpriteWorldP->pixelDepth <= 8)
  462.                     {
  463.                         (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  464.                         SetGWorld(tempMaskGWorldP, nil);
  465.                         InvertRect(&tempMaskGWorldP->portRect);
  466.                         UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  467.                     }
  468.                 }        // If no pixel Mask wanted, dispose
  469.                 else    // of the GWorld we used to make region
  470.                 {
  471.                     DisposeGWorld( tempMaskGWorldP );
  472.                     tempMaskGWorldP = NULL;
  473.                 }
  474.                 
  475.                 SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  476.                 SWSetCurrentFrameIndex(tempSpriteP, 0);
  477.                 tempSpriteP->sharedPictGWorld = tempPictGWorldP;
  478.                 tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
  479.                 
  480.                 *newSpriteP = tempSpriteP;
  481.             }
  482.         }
  483.     }
  484.     
  485.     if ( rectArrayHndl != NULL )
  486.     {
  487.         HUnlock( rectArrayHndl );
  488.         ReleaseResource( rectArrayHndl );
  489.     }
  490.     
  491.     SWSetStickyIfError( err );
  492.     return err;
  493. }
  494.  
  495.  
  496. ///--------------------------------------------------------------------------------------
  497. //  SWCreateSpriteFromSinglePictXY
  498. //
  499. //  height/width code contributed by Mohsan Khan, 96-06-13. You can email Mohsan Khan at
  500. //    xybernic@algonet.se, or visit his web page at www.algonet.se/~xybernic.
  501. ///--------------------------------------------------------------------------------------
  502.  
  503. SW_FUNC OSErr SWCreateSpriteFromSinglePictXY(
  504.         SpriteWorldPtr destSpriteWorldP,
  505.         SpritePtr* newSpriteP,
  506.         void* spriteStorageP,
  507.         short pictResID,
  508.         short maskResID,
  509.         short frameWidth,
  510.         short frameHeight,
  511.         short borderWidth,
  512.         short borderHeight,
  513.         short maxFrames,
  514.         MaskType maskType)
  515. {
  516.     OSErr            err = noErr;
  517.     PicHandle        tempPic;
  518.     GWorldPtr        tempPictGWorldP, 
  519.                     tempMaskGWorldP, 
  520.                     tempTempMaskGWorldP;
  521.     Rect            frameRect;
  522.     SpritePtr        tempSpriteP;
  523.     FramePtr        newFrameP;
  524.     short            frame;
  525.  
  526.     SW_ASSERT(destSpriteWorldP != NULL);
  527.  
  528.     tempPictGWorldP = NULL;
  529.     tempMaskGWorldP = NULL;
  530.     *newSpriteP = NULL;
  531.  
  532.  
  533.     tempPic = GetPicture( pictResID );
  534.     if ( tempPic == nil )
  535.     {
  536.         err = MemError();
  537.         if ( err == noErr )
  538.             err = resNotFound;
  539.     }
  540.     else
  541.     {
  542.         ReleaseResource( (Handle)tempPic );
  543.     }
  544.  
  545.     if ( err == noErr )
  546.     {    
  547.         {
  548.             err = SWCreateGWorldFromPictResource( destSpriteWorldP, &tempPictGWorldP, pictResID );
  549.             if ( err == noErr && maskType != kNoMask )
  550.                 err = SWCreateGWorldFromPictResource(
  551.                     destSpriteWorldP, &tempMaskGWorldP, maskResID );
  552.             if (err == noErr)
  553.             {
  554.                 if ( pictResID == maskResID && tempMaskGWorldP != NULL )
  555.                 {
  556.                     err = SWBlackenGWorld( tempMaskGWorldP );
  557.                 
  558.                     if (err == noErr)
  559.                         err = SWWhitenGWorld( tempPictGWorldP );
  560.                 }
  561.             }
  562.             if ( maxFrames == 0 )
  563.             {
  564.                 maxFrames = (tempPictGWorldP->portRect.right/frameWidth) *
  565.                             (tempPictGWorldP->portRect.bottom/frameHeight);
  566.             }
  567.             if (err == noErr)
  568.             {
  569.                 err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  570.             }
  571.             if (err == noErr)
  572.             {
  573.                 err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, frameWidth, 
  574.                         frameHeight, maskType );
  575.             }
  576.             if (err == noErr)
  577.             {
  578.                 frameRect.left = 0;
  579.                 frameRect.top = 0;
  580.                 frameRect.right = frameWidth;
  581.                 frameRect.bottom = frameHeight;
  582.                 
  583.                 for (frame = 0; frame < maxFrames; frame++)
  584.                 {
  585.                     err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
  586.                             tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
  587.  
  588.                     if (err == noErr)
  589.                     {
  590.                         err = SWAddFrame(tempSpriteP, newFrameP);
  591.                         if ( frame < maxFrames-1 )
  592.                         {
  593.                             frameRect.left += frameWidth + borderWidth;
  594.                             frameRect.right = frameRect.left + frameWidth;
  595.                             if ( frameRect.right > tempPictGWorldP->portRect.right )
  596.                             {
  597.                                 frameRect.left = 0;
  598.                                 frameRect.right = frameWidth;
  599.                                 frameRect.top += frameHeight + borderHeight;
  600.                                 frameRect.bottom = frameRect.top + frameHeight;
  601.                                 
  602.                                 if ( frameRect.bottom > tempPictGWorldP->portRect.bottom )
  603.                                 {
  604.                                     err = kOutOfRangeErr;
  605.                                 }
  606.                             }
  607.                         }
  608.                     }
  609.                     if ( err != noErr )
  610.                     {
  611.                         SWDisposeFrame(&newFrameP);
  612.                         SWDisposeSprite(&tempSpriteP);
  613.                         break;
  614.                     }
  615.                 } // end for
  616.                 SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
  617.             }
  618.  
  619.             if (err == noErr)
  620.             {
  621.                     // make a pixel mask
  622.                 if ((maskType & kPixelMask) != 0)
  623.                 {
  624.                     if (destSpriteWorldP->pixelDepth <= 8)
  625.                     {
  626.                         (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  627.                         SetGWorld(tempMaskGWorldP, nil);
  628.                         InvertRect(&tempMaskGWorldP->portRect);
  629.                         UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  630.                     }
  631.                 }        // If no pixel Mask wanted, dispose
  632.                 else    // of the GWorld we used to make region
  633.                 {
  634.                     DisposeGWorld( tempMaskGWorldP );
  635.                     tempMaskGWorldP = NULL;
  636.                 }
  637.                 
  638.                 SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  639.                 SWSetCurrentFrameIndex(tempSpriteP, 0);
  640.                 tempSpriteP->sharedPictGWorld = tempPictGWorldP;
  641.                 tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
  642.  
  643.                 *newSpriteP = tempSpriteP;
  644.             }
  645.         }
  646.     }
  647.     SWSetStickyIfError( err );
  648.     return err;
  649. }
  650.  
  651.  
  652. ///--------------------------------------------------------------------------------------
  653. //    SWUpdateSpriteFromPictResource
  654. ///--------------------------------------------------------------------------------------
  655.  
  656. SW_FUNC OSErr SWUpdateSpriteFromPictResource(
  657.     SpritePtr theSpriteP,
  658.     short pictResID)
  659. {
  660.     OSErr             err = noErr;
  661.     GDHandle        currentGDH;
  662.     GWorldPtr        currentGWorld;
  663.     GWorldPtr        frameGWorld;
  664.     PicHandle        pictH;
  665.     Rect            frameRect;
  666.     short            frame;
  667.     
  668.     SW_ASSERT(theSpriteP != NULL);
  669.     
  670.     GetGWorld( ¤tGWorld, ¤tGDH );
  671.     
  672.     SWLockSprite( theSpriteP );
  673.     
  674.     if ( theSpriteP->sharedPictGWorld != NULL )
  675.     {
  676.         SetGWorld( theSpriteP->sharedPictGWorld, NULL );
  677.         pictH = GetPicture( pictResID );
  678.         if ( pictH != NULL )
  679.         {
  680.             frameRect = theSpriteP->sharedPictGWorld->portRect;
  681.             EraseRect( &frameRect );
  682.             DrawPicture( pictH, &frameRect );
  683.             ReleaseResource( (Handle)pictH );
  684.         }
  685.         else
  686.         {
  687.             err = MemError();
  688.             if ( err == noErr )
  689.                 err = resNotFound;
  690.         }
  691.     }
  692.     else
  693.     {
  694.         for (frame = 0; frame < theSpriteP->maxFrames; frame++)
  695.         {
  696.             frameGWorld = theSpriteP->frameArray[frame]->framePort;
  697.             if ( frameGWorld != NULL )
  698.             {
  699.                 SetGWorld( frameGWorld, nil );
  700.                 pictH = GetPicture( pictResID + frame );
  701.                 if ( pictH != NULL )
  702.                 {
  703.                     frameRect = frameGWorld->portRect;
  704.                     EraseRect( &frameRect );
  705.                     DrawPicture( pictH, &frameRect );
  706.                     ReleaseResource( (Handle)pictH );
  707.                 }
  708.                 else
  709.                 {
  710.                     err = MemError();
  711.                     if ( err == noErr )
  712.                         err = resNotFound;
  713.                     break;
  714.                 }
  715.             }
  716.         }
  717.     }
  718.     SetGWorld( currentGWorld, currentGDH );
  719.     
  720.     SWSetStickyIfError( err );
  721.     return err;
  722. }
  723.  
  724.  
  725. ///--------------------------------------------------------------------------------------
  726. //    SWCloneSprite
  727. ///--------------------------------------------------------------------------------------
  728.  
  729. SW_FUNC OSErr SWCloneSprite(
  730.     SpritePtr    cloneSpriteP,
  731.     SpritePtr*    newSpriteP,
  732.     void*        spriteStorageP)
  733. {
  734.     SpritePtr         tempSpriteP;
  735.     short             index;
  736.     Size            frameArraySize;
  737.     OSErr             err = noErr;
  738.     
  739.     SW_ASSERT(cloneSpriteP != NULL);
  740.  
  741.         // Allocate memory for the new Sprite
  742.     tempSpriteP = (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
  743.     if (tempSpriteP == NULL)
  744.         err = MemError();
  745.  
  746.     if (err == noErr)
  747.     {
  748.             // copy the clone sprite into the temp sprite
  749.         *tempSpriteP = *cloneSpriteP;
  750.  
  751.             // clear the layer fields, in case the parent sprite is in a layer
  752.         tempSpriteP->parentSpriteLayerP = NULL;
  753.         tempSpriteP->nextSpriteP = NULL;
  754.         tempSpriteP->prevSpriteP = NULL;
  755.         
  756.         tempSpriteP->frameArrayIsShared = false;
  757.     }
  758.         
  759.     if (err == noErr)
  760.     {
  761.             // Create a new frameArray for this sprite
  762.         frameArraySize = (Size)cloneSpriteP->maxFrames * sizeof(FramePtr);
  763.         tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
  764.  
  765.         if (tempSpriteP->frameArray != NULL)
  766.         {
  767.                 // copy the frame array, and increment useCount for each frame
  768.             for (index = 0; index < cloneSpriteP->maxFrames; index++)
  769.             {
  770.                 tempSpriteP->frameArray[index] = cloneSpriteP->frameArray[index];
  771.                 tempSpriteP->frameArray[index]->useCount++;
  772.             }
  773.         }
  774.         else
  775.         {
  776.             err = MemError();
  777.             DisposePtr((Ptr)tempSpriteP);
  778.         }
  779.     }
  780.     
  781.     if (err == noErr)
  782.         *newSpriteP = tempSpriteP;
  783.  
  784.     SWSetStickyIfError( err );
  785.     return err;
  786. }
  787.  
  788.  
  789. ///--------------------------------------------------------------------------------------
  790. //    SWFastCloneSprite
  791. ///--------------------------------------------------------------------------------------
  792.  
  793. SW_FUNC OSErr SWFastCloneSprite(
  794.     SpritePtr    cloneSpriteP,
  795.     SpritePtr*    newSpriteP,
  796.     void*        spriteStorageP)
  797. {
  798.     SpritePtr         tempSpriteP;
  799.     OSErr             err = noErr;
  800.     
  801.     SW_ASSERT(cloneSpriteP != NULL);
  802.  
  803.         // Allocate memory for the new Sprite
  804.     tempSpriteP = (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
  805.     if (tempSpriteP == NULL)
  806.         err = MemError();
  807.  
  808.     if (err == noErr)
  809.     {
  810.             // copy the clone sprite into the temp sprite
  811.         *tempSpriteP = *cloneSpriteP;
  812.  
  813.             // clear the layer fields, in case the parent sprite is in a layer
  814.         tempSpriteP->parentSpriteLayerP = NULL;
  815.         tempSpriteP->nextSpriteP = NULL;
  816.         tempSpriteP->prevSpriteP = NULL;
  817.         
  818.         tempSpriteP->frameArrayIsShared = true;
  819.         *newSpriteP = tempSpriteP;
  820.     }
  821.  
  822.     SWSetStickyIfError( err );
  823.     return err;
  824. }
  825.  
  826.  
  827. ///--------------------------------------------------------------------------------------
  828. //    SWCloneSpriteFromTile
  829. ///--------------------------------------------------------------------------------------
  830.  
  831. SW_FUNC OSErr SWCloneSpriteFromTile(
  832.     SpriteWorldPtr spriteWorldP,
  833.     SpritePtr* newSpriteP,
  834.     void* spriteStorageP,
  835.     short firstTileID,
  836.     short lastTileID)
  837. {
  838.     OSErr             err;
  839.     SpritePtr         tempSpriteP;
  840.     FramePtr         tileFrameP;
  841.     short             curTileID, curIndex, numFrames;
  842.     
  843.     SW_ASSERT(firstTileID <= lastTileID);
  844.     SW_ASSERT(spriteWorldP->tileFrameArray != NULL);
  845.     
  846.     *newSpriteP = NULL;
  847.     numFrames = (lastTileID - firstTileID) + 1;
  848.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, numFrames);
  849.     
  850.     if (err == noErr)
  851.     {
  852.         for (curTileID = firstTileID; curTileID <= lastTileID; curTileID++)
  853.         {
  854.             tileFrameP = spriteWorldP->tileFrameArray[curTileID];
  855.             SW_ASSERT(tileFrameP != NULL);
  856.             err = SWAddFrame(tempSpriteP, tileFrameP);
  857.  
  858.             if (err != noErr)
  859.             {
  860.                 SWDisposeSprite(&tempSpriteP);
  861.                 break;
  862.             }
  863.         }
  864.  
  865.         if (err == noErr)
  866.         {
  867.             SWSetSpriteFrameRange(tempSpriteP, 0, numFrames - 1);
  868.             
  869.                 // Set current index to be the same as the Tile's current image, if possible.
  870.             curIndex = spriteWorldP->curTileImage[firstTileID];
  871.             if (curIndex >= firstTileID && curIndex <= lastTileID)
  872.                 curIndex = spriteWorldP->curTileImage[firstTileID] - firstTileID;
  873.             else
  874.                 curIndex = 0;
  875.             
  876.             SWSetCurrentFrameIndex(tempSpriteP, curIndex);
  877.             *newSpriteP = tempSpriteP;
  878.         }
  879.     }
  880.  
  881.     SWSetStickyIfError( err );
  882.     return err;
  883. }
  884.  
  885.  
  886. ///--------------------------------------------------------------------------------------
  887. //    SWRemoveSpriteFromAnimation
  888. ///--------------------------------------------------------------------------------------
  889.  
  890. SW_FUNC void  SWRemoveSpriteFromAnimation(
  891.     SpriteWorldPtr    spriteWorldP,
  892.     SpritePtr        spriteP,
  893.     Boolean            disposeOfSprite)
  894. {
  895.     SW_ASSERT(spriteWorldP != NULL && spriteP != NULL);
  896.     
  897.     SWSetSpriteVisible( spriteP, false );
  898.     SWRemoveSprite(spriteP);
  899.     SWAddSprite(spriteWorldP->deadSpriteLayerP, spriteP);
  900.     
  901.     if ( disposeOfSprite )
  902.     {
  903.         spriteP->spriteRemoval = kSWRemoveAndDisposeSprite;
  904.     }
  905.     else
  906.     {
  907.         spriteP->spriteRemoval = kSWRemoveSprite;
  908.     }
  909. }
  910.     
  911.  
  912. ///--------------------------------------------------------------------------------------
  913. //    SWDisposeSprite
  914. ///--------------------------------------------------------------------------------------
  915.  
  916. SW_FUNC void SWDisposeSprite(
  917.     SpritePtr *deadSpritePP)
  918. {
  919.     SpritePtr    deadSpriteP = *deadSpritePP;
  920.     
  921.     if (deadSpriteP != NULL)
  922.     {
  923.         SWCloseSprite(deadSpriteP);
  924.         DisposePtr((Ptr)deadSpriteP);
  925.         
  926.         *deadSpritePP = NULL;    // Set the original pointer to NULL
  927.     }
  928. }
  929.  
  930.  
  931. ///--------------------------------------------------------------------------------------
  932. //    SWCloseSprite
  933. ///--------------------------------------------------------------------------------------
  934.  
  935. SW_FUNC void SWCloseSprite(
  936.     SpritePtr deadSpriteP)
  937. {
  938.     short             frame;
  939.     Boolean            framesDisposed;
  940.     
  941.     if (deadSpriteP != NULL)
  942.     {
  943.             // Dispose the frames if they aren't shared, or if this is the master sprite
  944.         if (!deadSpriteP->frameArrayIsShared)
  945.         {
  946.             for (frame = 0; frame < deadSpriteP->numFrames; frame++)
  947.             {
  948.                 framesDisposed = SWDisposeFrame(&deadSpriteP->frameArray[frame]);
  949.             }
  950.             
  951.             if ( framesDisposed )
  952.             {
  953.                 if ( deadSpriteP->sharedPictGWorld != NULL )
  954.                 {
  955.                     DisposeGWorld(deadSpriteP->sharedPictGWorld );
  956.                     deadSpriteP->sharedPictGWorld = NULL;
  957.                 }
  958.             
  959.                 if ( deadSpriteP->sharedMaskGWorld != NULL )
  960.                 {
  961.                     DisposeGWorld(deadSpriteP->sharedMaskGWorld );
  962.                     deadSpriteP->sharedMaskGWorld = NULL;
  963.                 }
  964.             }
  965.             
  966.             DisposePtr((Ptr)deadSpriteP->frameArray);
  967.         }
  968.     }
  969. }
  970.  
  971.  
  972. ///--------------------------------------------------------------------------------------
  973. //    SWLockSprite
  974. ///--------------------------------------------------------------------------------------
  975.  
  976. SW_FUNC void SWLockSprite(
  977.     SpritePtr srcSpriteP)
  978. {
  979.     register long curFrame;
  980.     
  981.     SW_ASSERT(srcSpriteP != NULL);
  982.  
  983.     for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
  984.     {
  985.         SWLockFrame(srcSpriteP->frameArray[curFrame]);
  986.     }
  987. }
  988.  
  989.  
  990. ///--------------------------------------------------------------------------------------
  991. //    SWUnlockSprite
  992. ///--------------------------------------------------------------------------------------
  993.  
  994. SW_FUNC void SWUnlockSprite(
  995.     SpritePtr srcSpriteP)
  996. {
  997.     register long curFrame;
  998.     
  999.     SW_ASSERT(srcSpriteP != NULL);
  1000.  
  1001.     for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
  1002.     {
  1003.         SWUnlockFrame(srcSpriteP->frameArray[curFrame]);
  1004.     }
  1005. }
  1006.  
  1007.  
  1008. ///--------------------------------------------------------------------------------------
  1009. //    SWStdSpriteDrawProc - for drawing sprites
  1010. ///--------------------------------------------------------------------------------------
  1011.  
  1012. SW_FUNC void SWStdSpriteDrawProc(
  1013.     FramePtr srcFrameP,
  1014.     FramePtr dstFrameP,
  1015.     Rect* srcRect,
  1016.     Rect* dstRect)
  1017. {
  1018.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  1019.     
  1020.     if (srcFrameP->maskRgn != NULL)
  1021.     {
  1022.         Rect rgnRect = (**srcFrameP->maskRgn).rgnBBox;
  1023.  
  1024.             // move the mask region to the new sprite location
  1025.         OffsetRgn(srcFrameP->maskRgn,
  1026.             (dstRect->left - (srcRect->left - srcFrameP->frameRect.left) - rgnRect.left) 
  1027.             + srcFrameP->offsetPoint.h,
  1028.             (dstRect->top - (srcRect->top - srcFrameP->frameRect.top) - rgnRect.top)
  1029.             + srcFrameP->offsetPoint.v);
  1030.     }
  1031.     
  1032.         // CopyBits with a mask region is generally faster than CopyMask
  1033.     CopyBits((BitMapPtr)srcFrameP->framePix, (BitMapPtr)dstFrameP->framePix,
  1034.                 srcRect, dstRect, srcCopy, srcFrameP->maskRgn);
  1035. }
  1036.  
  1037.  
  1038. ///--------------------------------------------------------------------------------------
  1039. //    SWAddFrame
  1040. ///--------------------------------------------------------------------------------------
  1041.  
  1042. SW_FUNC OSErr SWAddFrame(
  1043.     SpritePtr srcSpriteP,
  1044.     FramePtr newFrameP)
  1045. {
  1046.     OSErr err = noErr;
  1047.     
  1048.     SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
  1049.     
  1050.         // don’t exceed maximum number of frames
  1051.     if (srcSpriteP->numFrames < srcSpriteP->maxFrames)
  1052.     {
  1053.         srcSpriteP->frameArray[srcSpriteP->numFrames] = newFrameP;
  1054.  
  1055.             // increment the number of frames
  1056.         srcSpriteP->numFrames++;
  1057.         newFrameP->useCount++;
  1058.     }
  1059.     else
  1060.     {
  1061.         err = kMaxFramesErr;
  1062.     }
  1063.  
  1064.     SWSetStickyIfError( err );
  1065.     return err;
  1066. }
  1067.  
  1068.  
  1069. ///--------------------------------------------------------------------------------------
  1070. //    SWInsertFrame
  1071. ///--------------------------------------------------------------------------------------
  1072.  
  1073. SW_FUNC OSErr SWInsertFrame(
  1074.     SpritePtr    srcSpriteP,
  1075.     FramePtr    newFrameP,
  1076.     long        frameIndex)
  1077. {
  1078.     register long        index;
  1079.     register FramePtr    *frameArray;
  1080.     OSErr                err = noErr;
  1081.     
  1082.     SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
  1083.     
  1084.     frameArray = srcSpriteP->frameArray;
  1085.  
  1086.         // don’t exceed maximum number of frames
  1087.     if (frameIndex < srcSpriteP->maxFrames && frameIndex >= 0 &&
  1088.         srcSpriteP->numFrames < srcSpriteP->maxFrames)
  1089.     {
  1090.             // move frames above frameIndex up
  1091.         for (index = srcSpriteP->numFrames; index > frameIndex; index--)
  1092.             frameArray[index] = frameArray[index - 1];
  1093.         
  1094.             // fill the hole
  1095.         frameArray[frameIndex] = newFrameP;
  1096.  
  1097.         srcSpriteP->numFrames++;
  1098.         newFrameP->useCount++;
  1099.     }
  1100.     else
  1101.     {
  1102.         err = kMaxFramesErr;
  1103.     }
  1104.  
  1105.     SWSetStickyIfError( err );
  1106.     return err;
  1107. }
  1108.  
  1109.  
  1110. ///--------------------------------------------------------------------------------------
  1111. //    SWRemoveFrame
  1112. ///--------------------------------------------------------------------------------------
  1113.  
  1114. SW_FUNC void SWRemoveFrame(
  1115.     SpritePtr srcSpriteP,
  1116.     FramePtr oldFrameP)
  1117. {
  1118.     register long curFrame;
  1119.     register FramePtr *frameArray;
  1120.     
  1121.     SW_ASSERT(srcSpriteP != NULL && oldFrameP != NULL);
  1122.  
  1123.     curFrame = srcSpriteP->numFrames;
  1124.     frameArray = srcSpriteP->frameArray;
  1125.  
  1126.         // find the frame to be removed
  1127.     while (curFrame--)
  1128.     {
  1129.         if (frameArray[curFrame] == oldFrameP)
  1130.         {
  1131.             srcSpriteP->numFrames--;
  1132.             oldFrameP->useCount--;
  1133.             
  1134.                 // move the rest of the frames down
  1135.             while (curFrame <= (srcSpriteP->numFrames - 1L))
  1136.             {
  1137.                 frameArray[curFrame] = frameArray[curFrame + 1L];
  1138.                 curFrame++;
  1139.             }
  1140.  
  1141.             break;
  1142.         }
  1143.     }
  1144. }
  1145.  
  1146. #pragma mark -
  1147. ///--------------------------------------------------------------------------------------
  1148. //    SWSetCurrentFrame
  1149. ///--------------------------------------------------------------------------------------
  1150.  
  1151. SW_FUNC OSErr SWSetCurrentFrame(
  1152.     SpritePtr srcSpriteP,
  1153.     FramePtr newFrameP)
  1154. {
  1155.     short        frameIndex = 0;
  1156.     Boolean        foundFrame = false;
  1157.     OSErr        err = noErr;
  1158.     
  1159.     SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
  1160.  
  1161.     for (frameIndex = 0; frameIndex < srcSpriteP->numFrames; frameIndex++)
  1162.     {
  1163.         if (srcSpriteP->frameArray[frameIndex] == newFrameP)
  1164.         {
  1165.             SWSetCurrentFrameIndex(srcSpriteP, frameIndex);
  1166.             foundFrame = true;
  1167.             break;
  1168.         }
  1169.     }
  1170.     
  1171.     if (foundFrame == false)
  1172.         err = kBadParameterErr;
  1173.     
  1174.     SWSetStickyIfError( err );
  1175.     return err;
  1176. }
  1177.  
  1178.  
  1179. ///--------------------------------------------------------------------------------------
  1180. //    SWSetCurrentFrameIndex
  1181. ///--------------------------------------------------------------------------------------
  1182.  
  1183. SW_FUNC void SWSetCurrentFrameIndex(
  1184.     SpritePtr srcSpriteP,
  1185.     short frameIndex)
  1186. {
  1187.     register FramePtr newFrameP;
  1188.     short horizOffset, vertOffset;
  1189.     
  1190.     SW_ASSERT(srcSpriteP != NULL && frameIndex >= 0);
  1191.  
  1192.     if (frameIndex < srcSpriteP->numFrames)
  1193.     {
  1194.         newFrameP = srcSpriteP->frameArray[frameIndex];
  1195.         
  1196.             // If this is a brand new sprite, it won't have a current frame.
  1197.             // (This is used when calculating the hotSpot offset from old to new frame.)
  1198.         if (srcSpriteP->curFrameP == NULL)
  1199.             srcSpriteP->curFrameP = newFrameP;
  1200.  
  1201.         horizOffset = (srcSpriteP->destFrameRect.left - newFrameP->frameRect.left) +
  1202.                     (srcSpriteP->curFrameP->hotSpotH - newFrameP->hotSpotH);
  1203.         vertOffset = (srcSpriteP->destFrameRect.top - newFrameP->frameRect.top) +
  1204.                     (srcSpriteP->curFrameP->hotSpotV - newFrameP->hotSpotV);
  1205.         
  1206.         srcSpriteP->curFrameP = newFrameP;
  1207.         srcSpriteP->destFrameRect = newFrameP->frameRect;
  1208.  
  1209.         if (srcSpriteP->scaledWidth > 0)
  1210.             srcSpriteP->destFrameRect.right = srcSpriteP->destFrameRect.left + 
  1211.                                                 srcSpriteP->scaledWidth;
  1212.         if (srcSpriteP->scaledHeight > 0)
  1213.             srcSpriteP->destFrameRect.bottom = srcSpriteP->destFrameRect.top + 
  1214.                                                 srcSpriteP->scaledHeight;
  1215.         
  1216.         
  1217.         srcSpriteP->destFrameRect.left += horizOffset;
  1218.         srcSpriteP->destFrameRect.right += horizOffset;
  1219.         srcSpriteP->destFrameRect.top += vertOffset;
  1220.         srcSpriteP->destFrameRect.bottom += vertOffset;
  1221.  
  1222.         srcSpriteP->curFrameIndex = frameIndex;
  1223.  
  1224.         srcSpriteP->needsToBeDrawn = true;
  1225.     }
  1226. }
  1227.  
  1228.  
  1229. ///--------------------------------------------------------------------------------------
  1230. //    SWSetSpriteCollideProc
  1231. ///--------------------------------------------------------------------------------------
  1232.  
  1233. SW_FUNC void SWSetSpriteCollideProc(
  1234.     SpritePtr srcSpriteP,
  1235.     CollideProcPtr collideProc)
  1236. {
  1237.     SW_ASSERT(srcSpriteP != NULL);
  1238.     srcSpriteP->spriteCollideProc = collideProc;
  1239. }
  1240.  
  1241.  
  1242. ///--------------------------------------------------------------------------------------
  1243. //    SWSetSpriteDrawProc
  1244. ///--------------------------------------------------------------------------------------
  1245.  
  1246. SW_FUNC OSErr SWSetSpriteDrawProc(
  1247.     SpritePtr srcSpriteP,
  1248.     DrawProcPtr drawProc)
  1249. {
  1250.     OSErr        err = noErr;
  1251.     FramePtr    headFrameP = NULL;
  1252.     short        framePixelDepth = 0;
  1253.     
  1254.     SW_ASSERT(srcSpriteP != NULL && drawProc != NULL);
  1255.     
  1256. #if SW_PPC
  1257.     if (drawProc == CompiledSprite8BitDrawProc)
  1258.         drawProc = BlitPixie8BitMaskDrawProc;
  1259. #endif
  1260.     
  1261.     headFrameP = srcSpriteP->frameArray[0];
  1262.     if ( headFrameP != NULL )
  1263.     {
  1264.         if ( headFrameP->framePort != NULL )
  1265.         {
  1266.             framePixelDepth = (*headFrameP->framePort->portPixMap)->pixelSize;
  1267.         }
  1268.     }
  1269.     
  1270.     if (framePixelDepth != 8)
  1271.     {
  1272.         if ( (drawProc == BlitPixie8BitRectDrawProc) ||
  1273.              (drawProc == BlitPixie8BitMaskDrawProc) ||
  1274.              (drawProc == BP8BitInterlacedRectDrawProc) ||
  1275.              (drawProc == BP8BitInterlacedMaskDrawProc) ||
  1276.              (drawProc == BlitPixie8BitPartialMaskDrawProc) ||
  1277.              (drawProc == BP8BitInterlacedPartialMaskDrawProc) ||
  1278.              (drawProc == CompiledSprite8BitDrawProc) )
  1279.         {
  1280.             err = kWrongDepthErr;
  1281.         }
  1282.     }
  1283.  
  1284.     if (headFrameP->maskPort == NULL)
  1285.     {
  1286.         if ( (drawProc == BlitPixie8BitMaskDrawProc) ||
  1287.              (drawProc == BP8BitInterlacedMaskDrawProc) ||
  1288.              (drawProc == BlitPixie8BitPartialMaskDrawProc) ||
  1289.              (drawProc == BP8BitInterlacedPartialMaskDrawProc) ||
  1290.              (drawProc == CompiledSprite8BitDrawProc) )
  1291.         {
  1292.             err = kWrongMaskErr;
  1293.         }
  1294.     }
  1295.     else if (drawProc == CompiledSprite8BitDrawProc && headFrameP->pixCodeH == NULL)
  1296.     {
  1297.         err = kSpriteNotCompiledErr;
  1298.     }
  1299.         
  1300.     if ( err == noErr )
  1301.         srcSpriteP->frameDrawProc = drawProc;
  1302.         
  1303.     SWSetStickyIfError( err );
  1304.     return err;
  1305. }
  1306.  
  1307.  
  1308. ///--------------------------------------------------------------------------------------
  1309. //    SWSetSpriteFrameAdvance
  1310. ///--------------------------------------------------------------------------------------
  1311.  
  1312. SW_FUNC void SWSetSpriteFrameAdvance(
  1313.     SpritePtr srcSpriteP,
  1314.     short frameAdvance)
  1315. {
  1316.     SW_ASSERT(srcSpriteP != NULL);
  1317.     srcSpriteP->frameAdvance = frameAdvance;
  1318. }
  1319.  
  1320.  
  1321. ///--------------------------------------------------------------------------------------
  1322. //    SWSetSpriteFrameAdvanceMode
  1323. ///--------------------------------------------------------------------------------------
  1324.  
  1325. SW_FUNC void SWSetSpriteFrameAdvanceMode(
  1326.     SpritePtr srcSpriteP,
  1327.     AdvanceType advanceMode)
  1328. {
  1329.     SW_ASSERT(srcSpriteP != NULL);
  1330.     srcSpriteP->frameAdvanceMode = advanceMode;
  1331. }
  1332.  
  1333.  
  1334. ///--------------------------------------------------------------------------------------
  1335. //    SWSetSpriteFrameRange
  1336. ///--------------------------------------------------------------------------------------
  1337.  
  1338. SW_FUNC void SWSetSpriteFrameRange(
  1339.     SpritePtr srcSpriteP,
  1340.     short firstFrameIndex,
  1341.     short lastFrameIndex)
  1342. {
  1343.     SW_ASSERT(srcSpriteP != NULL);
  1344.     
  1345.     if ( firstFrameIndex < 0 )
  1346.         firstFrameIndex = 0;
  1347.     
  1348.     if ( lastFrameIndex > srcSpriteP->maxFrames - 1 )
  1349.         lastFrameIndex = srcSpriteP->maxFrames - 1;
  1350.     
  1351.     srcSpriteP->firstFrameIndex = firstFrameIndex;
  1352.     srcSpriteP->lastFrameIndex = lastFrameIndex;
  1353.     
  1354.         // Make sure the sprite's curFrameIndex is within the new frame range
  1355.     if (srcSpriteP->curFrameIndex < firstFrameIndex)
  1356.         SWSetCurrentFrameIndex(srcSpriteP, firstFrameIndex);
  1357.     else if (srcSpriteP->curFrameIndex > lastFrameIndex)
  1358.         SWSetCurrentFrameIndex(srcSpriteP, lastFrameIndex);
  1359. }
  1360.  
  1361.  
  1362. ///--------------------------------------------------------------------------------------
  1363. //    SWSetSpriteFrameTime
  1364. ///--------------------------------------------------------------------------------------
  1365.  
  1366. SW_FUNC void SWSetSpriteFrameTime(
  1367.     SpritePtr srcSpriteP,
  1368.     long timeInterval)
  1369. {
  1370.     SW_ASSERT(srcSpriteP != NULL);
  1371.     srcSpriteP->frameTimeInterval = timeInterval;
  1372. }
  1373.  
  1374.  
  1375. ///--------------------------------------------------------------------------------------
  1376. //    SWSetSpriteFrameProc
  1377. ///--------------------------------------------------------------------------------------
  1378.  
  1379. SW_FUNC void SWSetSpriteFrameProc(
  1380.     SpritePtr srcSpriteP,
  1381.     FrameProcPtr frameProc)
  1382. {
  1383.     SW_ASSERT(srcSpriteP != NULL);
  1384.     srcSpriteP->frameChangeProc = frameProc;
  1385. }
  1386.  
  1387.  
  1388. ///--------------------------------------------------------------------------------------
  1389. //    SWSetSpriteLocation
  1390. ///--------------------------------------------------------------------------------------
  1391.  
  1392. SW_FUNC void SWSetSpriteLocation(
  1393.     SpritePtr srcSpriteP,
  1394.     short horizLoc,
  1395.     short vertLoc)
  1396. {
  1397.     SW_ASSERT(srcSpriteP != NULL);
  1398.     
  1399.     horizLoc -= srcSpriteP->curFrameP->hotSpotH;
  1400.     vertLoc -= srcSpriteP->curFrameP->hotSpotV;
  1401.     
  1402.     srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom - 
  1403.                                                 srcSpriteP->destFrameRect.top);
  1404.     srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right - 
  1405.                                                 srcSpriteP->destFrameRect.left);
  1406.     srcSpriteP->destFrameRect.top = vertLoc;
  1407.     srcSpriteP->destFrameRect.left = horizLoc;
  1408.  
  1409.     srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
  1410.     srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
  1411.     srcSpriteP->needsToBeDrawn = true;
  1412. }
  1413.  
  1414.  
  1415. ///--------------------------------------------------------------------------------------
  1416. //    SWSetSpriteMoveBounds
  1417. ///--------------------------------------------------------------------------------------
  1418.  
  1419. SW_FUNC void SWSetSpriteMoveBounds(
  1420.     SpritePtr srcSpriteP,
  1421.     Rect* moveBoundsRect)
  1422. {
  1423.     SW_ASSERT(srcSpriteP != NULL);
  1424.     srcSpriteP->moveBoundsRect = *moveBoundsRect;
  1425. }
  1426.  
  1427.  
  1428. ///--------------------------------------------------------------------------------------
  1429. //    SWSetSpriteMoveDelta
  1430. ///--------------------------------------------------------------------------------------
  1431.  
  1432. SW_FUNC void SWSetSpriteMoveDelta(
  1433.     SpritePtr srcSpriteP,
  1434.     short horizDelta,
  1435.     short vertDelta)
  1436. {
  1437.     SW_ASSERT(srcSpriteP != NULL);
  1438.     
  1439.         // set sprite’s velocity
  1440.     srcSpriteP->horizMoveDelta = horizDelta;
  1441.     srcSpriteP->vertMoveDelta = vertDelta;
  1442. }
  1443.  
  1444.  
  1445. ///--------------------------------------------------------------------------------------
  1446. //    SWSetSpriteMoveTime
  1447. ///--------------------------------------------------------------------------------------
  1448.  
  1449. SW_FUNC void SWSetSpriteMoveTime(
  1450.     SpritePtr srcSpriteP,
  1451.     long timeInterval)
  1452. {
  1453.     SW_ASSERT(srcSpriteP != NULL);
  1454.     srcSpriteP->moveTimeInterval = timeInterval;
  1455. }
  1456.  
  1457.  
  1458. ///--------------------------------------------------------------------------------------
  1459. //    SWSetSpriteMoveProc
  1460. ///--------------------------------------------------------------------------------------
  1461.  
  1462. SW_FUNC void SWSetSpriteMoveProc(
  1463.     SpritePtr srcSpriteP,
  1464.     MoveProcPtr moveProc)
  1465. {
  1466.     SW_ASSERT(srcSpriteP != NULL);
  1467.     srcSpriteP->spriteMoveProc = moveProc;
  1468. }
  1469.  
  1470.  
  1471. ///--------------------------------------------------------------------------------------
  1472. //    SWSetSpriteVisible
  1473. ///--------------------------------------------------------------------------------------
  1474.  
  1475. SW_FUNC void SWSetSpriteVisible(
  1476.     SpritePtr srcSpriteP,
  1477.     Boolean isVisible)
  1478. {
  1479.     SW_ASSERT(srcSpriteP != NULL);
  1480.     srcSpriteP->isVisible = isVisible;
  1481.     srcSpriteP->needsToBeDrawn = true;
  1482.     srcSpriteP->needsToBeErased = !isVisible;
  1483. }
  1484.  
  1485.  
  1486. #pragma mark -
  1487. ///--------------------------------------------------------------------------------------
  1488. //    SWMoveSprite
  1489. ///--------------------------------------------------------------------------------------
  1490.  
  1491. SW_FUNC void SWMoveSprite(
  1492.     SpritePtr srcSpriteP,
  1493.     short horizLoc,
  1494.     short vertLoc)
  1495. {
  1496.     SW_ASSERT(srcSpriteP != NULL);
  1497.     
  1498.     horizLoc -= srcSpriteP->curFrameP->hotSpotH;
  1499.     vertLoc -= srcSpriteP->curFrameP->hotSpotV;
  1500.     
  1501.     if ((horizLoc != srcSpriteP->destFrameRect.left) || 
  1502.         (vertLoc != srcSpriteP->destFrameRect.top) )
  1503.     {
  1504.         srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom - 
  1505.                                                     srcSpriteP->destFrameRect.top);
  1506.         srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right - 
  1507.                                                     srcSpriteP->destFrameRect.left);
  1508.         srcSpriteP->destFrameRect.top = vertLoc;
  1509.         srcSpriteP->destFrameRect.left = horizLoc;
  1510.     
  1511.         srcSpriteP->needsToBeDrawn = true;
  1512.     }
  1513. }
  1514.  
  1515.  
  1516. ///--------------------------------------------------------------------------------------
  1517. //    SWOffsetSprite
  1518. ///--------------------------------------------------------------------------------------
  1519.  
  1520. SW_FUNC void SWOffsetSprite(
  1521.     SpritePtr srcSpriteP,
  1522.     short horizOffset,
  1523.     short vertOffset)
  1524. {
  1525.     SW_ASSERT(srcSpriteP != NULL);
  1526.     
  1527.     if ((horizOffset != 0) || (vertOffset != 0))
  1528.     {
  1529.         srcSpriteP->destFrameRect.right += horizOffset;
  1530.         srcSpriteP->destFrameRect.bottom += vertOffset;
  1531.         srcSpriteP->destFrameRect.left += horizOffset;
  1532.         srcSpriteP->destFrameRect.top += vertOffset;
  1533.         
  1534.         srcSpriteP->needsToBeDrawn = true;
  1535.     }
  1536. }
  1537.  
  1538.  
  1539. ///--------------------------------------------------------------------------------------
  1540. //    SWBounceSprite
  1541. ///--------------------------------------------------------------------------------------
  1542.  
  1543. SW_FUNC Boolean SWBounceSprite(
  1544.     SpritePtr srcSpriteP)
  1545. {
  1546.     short    horizOffset, vertOffset;
  1547.     
  1548.     SW_ASSERT(srcSpriteP != NULL);
  1549.  
  1550.         // Hit left side or right side
  1551.     if (srcSpriteP->destFrameRect.left < srcSpriteP->moveBoundsRect.left)
  1552.     {
  1553.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  1554.         horizOffset = (srcSpriteP->moveBoundsRect.left - srcSpriteP->destFrameRect.left) * 2;
  1555.     }
  1556.     else if (srcSpriteP->destFrameRect.right > srcSpriteP->moveBoundsRect.right)
  1557.     {
  1558.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  1559.         horizOffset = (srcSpriteP->moveBoundsRect.right - srcSpriteP->destFrameRect.right) * 2;
  1560.     }
  1561.     else
  1562.         horizOffset = 0;
  1563.  
  1564.  
  1565.         // Hit top or bottom
  1566.     if (srcSpriteP->destFrameRect.top < srcSpriteP->moveBoundsRect.top)
  1567.     {
  1568.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  1569.         vertOffset = (srcSpriteP->moveBoundsRect.top - srcSpriteP->destFrameRect.top) * 2;
  1570.     }
  1571.     else if (srcSpriteP->destFrameRect.bottom > srcSpriteP->moveBoundsRect.bottom)
  1572.     {
  1573.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  1574.         vertOffset = (srcSpriteP->moveBoundsRect.bottom - srcSpriteP->destFrameRect.bottom) * 2;
  1575.     }
  1576.     else
  1577.         vertOffset = 0;
  1578.     
  1579.     
  1580.         // Bounce the sprite if it had a collision with the wall
  1581.     if ((horizOffset != 0) || (vertOffset != 0))
  1582.     {
  1583.         SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
  1584.         return true;
  1585.     }
  1586.     else
  1587.     {
  1588.         return false;
  1589.     }
  1590. }
  1591.  
  1592.  
  1593. ///--------------------------------------------------------------------------------------
  1594. //    SWWrapSprite
  1595. ///--------------------------------------------------------------------------------------
  1596.  
  1597. SW_FUNC Boolean SWWrapSprite(
  1598.     SpritePtr srcSpriteP)
  1599. {
  1600.     short    horizOffset, vertOffset;
  1601.     
  1602.     SW_ASSERT(srcSpriteP != NULL);
  1603.     
  1604.         // Wrap to left or right
  1605.     if (srcSpriteP->oldFrameRect.left > srcSpriteP->moveBoundsRect.right)
  1606.     {
  1607.         horizOffset = - ((srcSpriteP->moveBoundsRect.right -
  1608.                         srcSpriteP->moveBoundsRect.left) +
  1609.                         (srcSpriteP->destFrameRect.right - 
  1610.                         srcSpriteP->destFrameRect.left) + srcSpriteP->horizMoveDelta);
  1611.     }
  1612.     else if (srcSpriteP->oldFrameRect.right < srcSpriteP->moveBoundsRect.left)
  1613.     {
  1614.         horizOffset = (srcSpriteP->moveBoundsRect.right -
  1615.                         srcSpriteP->moveBoundsRect.left) +
  1616.                         (srcSpriteP->destFrameRect.right - 
  1617.                         srcSpriteP->destFrameRect.left) - srcSpriteP->horizMoveDelta;
  1618.     }
  1619.     else
  1620.         horizOffset = 0;
  1621.     
  1622.     
  1623.         // Wrap to top or bottom
  1624.     if (srcSpriteP->oldFrameRect.top > srcSpriteP->moveBoundsRect.bottom)
  1625.     {
  1626.         vertOffset = -((srcSpriteP->moveBoundsRect.bottom -
  1627.                             srcSpriteP->moveBoundsRect.top) +
  1628.                             (srcSpriteP->destFrameRect.bottom - 
  1629.                             srcSpriteP->destFrameRect.top) + srcSpriteP->vertMoveDelta);
  1630.     }
  1631.     else if (srcSpriteP->oldFrameRect.bottom < srcSpriteP->moveBoundsRect.top)
  1632.     {
  1633.         vertOffset = (srcSpriteP->moveBoundsRect.bottom -
  1634.                             srcSpriteP->moveBoundsRect.top) +
  1635.                             (srcSpriteP->destFrameRect.bottom - 
  1636.                             srcSpriteP->destFrameRect.top) - srcSpriteP->vertMoveDelta;
  1637.     }
  1638.     else
  1639.         vertOffset = 0;
  1640.     
  1641.     
  1642.         // Wrap sprite, and set delta and old rects to current rect
  1643.     if ((horizOffset != 0) || (vertOffset != 0))
  1644.     {
  1645.         SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
  1646.         
  1647.         srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
  1648.         srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
  1649.         
  1650.         return true;
  1651.     }
  1652.     else
  1653.     {
  1654.         return false;
  1655.     }
  1656. }
  1657.  
  1658.  
  1659. ///--------------------------------------------------------------------------------------
  1660. // SWRegionCollision
  1661. ///--------------------------------------------------------------------------------------
  1662.  
  1663. SW_FUNC Boolean SWRegionCollision(
  1664.     SpritePtr srcSpriteP,
  1665.     SpritePtr dstSpriteP)
  1666. {
  1667.     Rect                 rgnRect;
  1668.  
  1669.      SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  1670.      SW_ASSERT(srcSpriteP->curFrameP->maskRgn != NULL);
  1671.      SW_ASSERT(dstSpriteP->curFrameP->maskRgn != NULL);
  1672.  
  1673.         // copy one of the regions in case they're the same 
  1674.         // (would happen if the sprites are clones using the same frame)
  1675.     CopyRgn( dstSpriteP->curFrameP->maskRgn, gCollisionSpareRgn );
  1676.     
  1677.     rgnRect = (**srcSpriteP->curFrameP->maskRgn).rgnBBox;
  1678.  
  1679.         // move the mask region to the new sprite location
  1680.     OffsetRgn(srcSpriteP->curFrameP->maskRgn,
  1681.                 (srcSpriteP->destFrameRect.left - rgnRect.left) +
  1682.                 srcSpriteP->curFrameP->offsetPoint.h,
  1683.                 (srcSpriteP->destFrameRect.top - rgnRect.top) +
  1684.                 srcSpriteP->curFrameP->offsetPoint.v);
  1685.  
  1686.     rgnRect = (**gCollisionSpareRgn).rgnBBox;
  1687.  
  1688.         // move the mask region to the new sprite location
  1689.     OffsetRgn(gCollisionSpareRgn,
  1690.                 (dstSpriteP->destFrameRect.left - rgnRect.left) +
  1691.                 dstSpriteP->curFrameP->offsetPoint.h,
  1692.                 (dstSpriteP->destFrameRect.top - rgnRect.top) +
  1693.                 dstSpriteP->curFrameP->offsetPoint.v);
  1694.  
  1695.     SectRgn(srcSpriteP->curFrameP->maskRgn, gCollisionSpareRgn, gCollisionSectRgn);
  1696.  
  1697.     return (!EmptyRgn(gCollisionSectRgn));
  1698. }
  1699.  
  1700.  
  1701. ///--------------------------------------------------------------------------------------
  1702. // SWRadiusCollision
  1703. ///--------------------------------------------------------------------------------------
  1704.  
  1705. SW_FUNC Boolean SWRadiusCollision(
  1706.     SpritePtr srcSpriteP,
  1707.     SpritePtr dstSpriteP)
  1708. {
  1709.     Point                 centerOne, centerTwo;
  1710.     register short        radiusOne, radiusTwo;
  1711.     register short        horizDistance, vertDistance;
  1712.     
  1713.     SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  1714.  
  1715.         // get radii - - assumes circular sprites!
  1716.     radiusOne = (srcSpriteP->destFrameRect.right-srcSpriteP->destFrameRect.left)/2;
  1717.     radiusTwo = (dstSpriteP->destFrameRect.right-dstSpriteP->destFrameRect.left)/2;
  1718.     
  1719.         // find centers
  1720.     centerOne.h = srcSpriteP->destFrameRect.left + radiusOne;
  1721.     centerOne.v = srcSpriteP->destFrameRect.top + radiusOne;
  1722.     centerTwo.h = dstSpriteP->destFrameRect.left + radiusTwo;
  1723.     centerTwo.v = dstSpriteP->destFrameRect.top + radiusTwo;
  1724.                     
  1725.     horizDistance = centerOne.h - centerTwo.h;
  1726.     vertDistance = centerOne.v - centerTwo.v;
  1727.  
  1728.     return ( (horizDistance*horizDistance) + (vertDistance*vertDistance) <
  1729.         ((radiusOne+radiusTwo)*(radiusOne+radiusTwo)) );
  1730. }
  1731.  
  1732.  
  1733. ///--------------------------------------------------------------------------------------
  1734. // SWPixelCollision
  1735. ///--------------------------------------------------------------------------------------
  1736.  
  1737. SW_FUNC Boolean SWPixelCollision(
  1738.     SpritePtr srcSpriteP,
  1739.     SpritePtr dstSpriteP)
  1740. {
  1741.     Boolean            collision;
  1742.     Rect            sectRect;
  1743.     FramePtr        srcFrameP,
  1744.                     dstFrameP;
  1745.     short            numBytesPerRow;
  1746.     short            srcPieceTop,
  1747.                     srcPieceLeft,
  1748.                     dstPieceTop,
  1749.                     dstPieceLeft;
  1750.     unsigned long     srcBaseOffset,
  1751.                     dstBaseOffset;
  1752.     unsigned char*    srcPixelPtr;
  1753.     unsigned char*    dstPixelPtr;
  1754.     short            i, j;
  1755.     
  1756.     SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  1757.      SW_ASSERT(srcSpriteP->curFrameP->maskPort != NULL);
  1758.      SW_ASSERT(dstSpriteP->curFrameP->maskPort != NULL);
  1759.      SW_ASSERT(srcSpriteP->curFrameP->isFrameLocked);
  1760.      SW_ASSERT(dstSpriteP->curFrameP->isFrameLocked);
  1761.         
  1762.     collision = false;
  1763.         
  1764.     sectRect.left =
  1765.         SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
  1766.     sectRect.top =
  1767.         SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
  1768.     sectRect.right =
  1769.         SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
  1770.     sectRect.bottom =
  1771.         SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
  1772.     
  1773.     if ( sectRect.right > sectRect.left && sectRect.bottom > sectRect.top )
  1774.     {
  1775.         START_32_BIT_MODE
  1776.         
  1777.         srcFrameP = srcSpriteP->curFrameP;
  1778.         dstFrameP = dstSpriteP->curFrameP;
  1779.         
  1780.             // Make sure we're in 8-bit
  1781.         if (srcFrameP->framePix->pixelSize != 8)
  1782.             return false;
  1783.     
  1784.             // calculate the top left of the intersecting portions of the frameRects
  1785.         srcPieceTop = srcFrameP->frameRect.top + (sectRect.top-srcSpriteP->destFrameRect.top);
  1786.         srcPieceLeft = srcFrameP->frameRect.left + (sectRect.left-srcSpriteP->destFrameRect.left);
  1787.         dstPieceTop = dstFrameP->frameRect.top + (sectRect.top-dstSpriteP->destFrameRect.top);
  1788.         dstPieceLeft = dstFrameP->frameRect.left + (sectRect.left-dstSpriteP->destFrameRect.left);
  1789.         
  1790.             // calculate the offset to the first byte of the sectRect of srcSprite
  1791.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcPieceTop - srcFrameP->frameRect.top] + 
  1792.             srcPieceLeft;
  1793.             
  1794.             // ... and for the dstSprite
  1795.         dstBaseOffset = dstFrameP->scanLinePtrArray[dstPieceTop - dstFrameP->frameRect.top] + 
  1796.             dstPieceLeft;
  1797.         
  1798.             // calculate pointers to the mask pixels within the overlapping sections
  1799.         srcPixelPtr = (unsigned char*)(srcFrameP->maskBaseAddr + srcBaseOffset);
  1800.         dstPixelPtr = (unsigned char*)(dstFrameP->maskBaseAddr + dstBaseOffset);
  1801.         
  1802.             // calculate the number of bytes in a row
  1803.         numBytesPerRow = (sectRect.right - sectRect.left);
  1804.         
  1805.         i = 0;
  1806.         while ( i < sectRect.bottom-sectRect.top && !collision )
  1807.         {
  1808.             j = 0;
  1809.             while ( j < numBytesPerRow && !collision )
  1810.             {
  1811.                 j++;
  1812.                 collision = ( (*srcPixelPtr | *dstPixelPtr) == 0 );
  1813.                 srcPixelPtr++;
  1814.                 dstPixelPtr++;
  1815.             }
  1816.             i++;
  1817.             srcPixelPtr += (unsigned long)(srcFrameP->frameRowBytes - numBytesPerRow);
  1818.             dstPixelPtr += (unsigned long)(dstFrameP->frameRowBytes - numBytesPerRow);
  1819.         }
  1820.         
  1821.         END_32_BIT_MODE
  1822.     }
  1823.     return collision;
  1824. }
  1825.  
  1826.  
  1827. ///--------------------------------------------------------------------------------------
  1828. //    SWIsSpriteInRect
  1829. ///--------------------------------------------------------------------------------------
  1830.  
  1831. SW_FUNC Boolean SWIsSpriteInRect(
  1832.     SpritePtr srcSpriteP,
  1833.     Rect* testRect)
  1834. {
  1835.     SW_ASSERT(srcSpriteP != NULL);
  1836.     
  1837.     return ((srcSpriteP->destFrameRect.top < testRect->bottom) &&
  1838.             (srcSpriteP->destFrameRect.bottom > testRect->top) &&
  1839.              (srcSpriteP->destFrameRect.left < testRect->right) &&
  1840.              (srcSpriteP->destFrameRect.right > testRect->left));
  1841. }
  1842.  
  1843. ///--------------------------------------------------------------------------------------
  1844. //    SWIsSpriteFullyInRect
  1845. ///--------------------------------------------------------------------------------------
  1846.  
  1847. SW_FUNC Boolean SWIsSpriteFullyInRect(
  1848.     SpritePtr srcSpriteP,
  1849.     Rect* testRect)
  1850. {
  1851.     SW_ASSERT(srcSpriteP != NULL);
  1852.     
  1853.     return ((srcSpriteP->destFrameRect.top >= testRect->top) &&
  1854.             (srcSpriteP->destFrameRect.bottom <= testRect->bottom) &&
  1855.              (srcSpriteP->destFrameRect.left >= testRect->left) &&
  1856.              (srcSpriteP->destFrameRect.right <= testRect->right));
  1857. }
  1858.  
  1859. ///--------------------------------------------------------------------------------------
  1860. //    SWIsPointInSprite
  1861. ///--------------------------------------------------------------------------------------
  1862.  
  1863. SW_FUNC Boolean SWIsPointInSprite(
  1864.     SpritePtr srcSpriteP,
  1865.     Point testPoint)
  1866. {
  1867.     SW_ASSERT(srcSpriteP != NULL);
  1868.     
  1869.     return    (testPoint.h >= srcSpriteP->destFrameRect.left) &&
  1870.             (testPoint.h < srcSpriteP->destFrameRect.right) &&
  1871.             (testPoint.v >= srcSpriteP->destFrameRect.top) &&
  1872.             (testPoint.v < srcSpriteP->destFrameRect.bottom);
  1873. }
  1874.  
  1875.